Passed
Branchmaster (4d7246)
by Plamen
01:28
created

table.js ➔ ... ➔ this.columnHoverRelease   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 5
c 1
b 0
f 0
nc 4
nop 2
dl 0
loc 9
rs 10
1
var strAsc = String.fromCharCode(9650); //▲
2
var strDesc = String.fromCharCode(9660);//▼
3
var xmlhttp;
4
var d;
5
6
var table = new function(){
7
    this.rq = null;
8
    this.tail = [];
9
10
    this.ReloadData = function(tableId){
11
        var request = {};
12
        this.BuildRequest(request, tableId);
13
        this.LoadData(tableId, request);
14
    };
15
16
    this.BuildRequest = function(request, crntTableId, skipPropertyArray){
17
        this.rq = request;
18
        this.checkSkip = function(skipProperty){
19
            var result = false;
20
            if(skipPropertyArray && Object.prototype.toString
21
                    .call(skipPropertyArray) === '[object Array]'
22
                    ){
23
                if(skipPropertyArray.indexOf(skipProperty) >= 0){
24
                    result = true;
25
                }
26
            }
27
            return result;
28
        };
29
        this.getSort = function(){
30
            var thTags = document.getElementById(crntTableId)
31
                    .getElementsByTagName("thead")[0]
32
                    .getElementsByTagName("th");
33
            var length = thTags.length;
34
            for(var i = 0; i < length; i++){
35
                var link = thTags[i].getElementsByTagName("a")[0];
36
                if(link && link.getElementsByTagName("span").length === 1){
37
                    var order = link.getElementsByTagName("span")[0].innerHTML;
38
                    if(order.length === 1){
39
                        this.rq.colNo = i;
40
                        this.rq.colOrd = (order === window.strDesc) ?
41
                                "desc" : "asc";
42
                        break;
43
                    }
44
                }
45
            }
46
        };
47
        this.getFilter = function(){
48
            var r = this.getFilterFieldsByTbaleID(crntTableId);
49
            if(r.filter !== null){
50
                this.rq.filter = r.filter;
51
            }
52
            if(r.filterBy !== null){
53
                this.rq.filterBy = r.filterBy;
54
            }
55
        };
56
57
        /* Build request object */
58
        if(!this.checkSkip("sort")){
59
            this.getSort();
60
        }
61
        if(!this.checkSkip("filter")){
62
            this.getFilter();
63
        }
64
65
        this.rq.tableId = crntTableId;
66
        return this.rq;
67
    };
68
69
    this.RequestToUrl = function(rq){
70
        var url = location.pathname + ".json" + location.search;
71
        if(typeof rq === "object"){
72
            var getUrlVarName = {
73
                colNo: "col", colOrd: "ord", filter: "filter",
74
                filterBy: "filter-by", pageNo: "pg", exportType: "export",
75
                tableId: "table-id"
76
            };
77
            var flagFirst = location.search.length < 1 ? true : false;
78
            for(var r in rq){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
79
                var clue = flagFirst === true ? "?" : "&";
80
                url += clue + getUrlVarName[r] + "=" + rq[r];
81
                flagFirst = false;
82
            }
83
        }
84
        return url;
85
    };
86
87
    this.Filter = function(field){
88
        var crntTableId = this.FilterGetTableId(field);
89
        if(crntTableId !== null){
90
            var request = {};
91
            var exRq = this.rq;
92
            this.BuildRequest(request, crntTableId);
93
            if(exRq === null ||
94
                    request.filter !== exRq.filter ||
95
                    request.filterBy !== exRq.filterBy
96
                    ){
97
                this.LoadData(crntTableId, request);
98
            }
99
        }
100
    };
101
102
    this.FilterGetTableId = function(field){
103
        if(field.tagName.toLowerCase() !== "select"){
104
            return field.getAttribute("data-table-id");
105
        }else{
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
106
            var f = field.parentNode.parentNode.getElementsByTagName("input")[0];
107
            return '' === f.value ? null : f.getAttribute("data-table-id");
108
        }
109
    };
110
111
    this.GoPage = function(lnk){
112
        var request = {};
113
        var table = this.getParent(lnk, "table");
114
        var crntTableId = table.getAttribute("id");
115
        this.BuildRequest(request, crntTableId);
116
        //check & serve pagination jump links
117
        var jumpDir = lnk.innerHTML.trim().substr(0, 1);
118
        if(jumpDir === "+" || jumpDir === "-"){
119
            var current = table.querySelector("tfoot .paging .a").innerHTML;
120
            var jump = lnk.innerHTML.replace("K", "000").replace("M", "000000000");
121
            var jumpPage = (parseInt(current) + parseInt(jump));
122
            lnk.parentNode.setAttribute("data-page", jumpPage);
123
            lnk.style.transform = "none";
124
        }
125
        request.pageNo = lnk.parentNode.hasAttribute("data-page") ?
126
                lnk.parentNode.getAttribute("data-page") :
127
                lnk.innerHTML;
128
        this.LoadData(crntTableId, request);
129
        return false;
130
    };
131
132
    this.Export = function(lnk, eType){
133
        var request = {};
134
        var crntTableId = this.getParent(lnk, "table").getAttribute("id");
135
        this.BuildRequest(request, crntTableId);
136
        request.exportType = ["CSV", "Excel"].indexOf(eType) >= 0 ? eType : "csv";
137
        window.open(this.RequestToUrl(request));
138
        return false;
139
    };
140
141
    this.Sort = function(colNo, lnk){
142
        var request = {};
143
        var crntTableId = this.getParent(lnk, "table").getAttribute("id");
144
        this.BuildRequest(request, crntTableId);
145
        if(Math.round(colNo) === request.colNo){
146
            request.colOrd = request.colOrd === "asc" ? "desc" : "asc";
147
        }else{
148
            request.colNo = Math.round(colNo);
149
            request.colOrd = "asc";
150
        }
151
        this.LoadData(crntTableId, request);
152
        /* Clear and add new sort arrow */
153
        var headSpans = this.getParent(lnk, "thead").getElementsByTagName("span");
154
        var length = headSpans.length;
155
        for(var i = 0; i < length; i++){
156
            headSpans[i].innerHTML = "";
157
        }
158
        lnk.getElementsByTagName("span")[0].innerHTML = (request.colOrd === "desc" ? window.strDesc : window.strAsc);
159
    };
160
161
    this.DrawSection = function(tableContainer, dt, tSection){
162
        var section = tSection === "tfoot" ? "tfoot" : "tbody";
163
        tSection = document.getElementById(tableContainer).
164
                getElementsByTagName(section)[0];
165
        this.clearSection(tSection);
166
        for(var i = 0; i < dt.length; i++){
167
            var row = dt[i];
168
            var tRow = document.createElement("tr");
169
170
            this.DrawRow(row, tRow);
171
172
            tSection.appendChild(tRow);
173
            if(section === "tfoot"){
174
                this.footerProcessPaginationLinks(tSection);
175
            }
176
            this.AppendRowCalback(tableContainer);
177
        }
178
    };
179
180
    this.DrawRow = function(row, tRow){
181
        for(var cell in row){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
182
            var tCell = document.createElement("td");
183
            if(typeof row[cell] === "string" || typeof row[cell] === "number"){
184
                tCell.innerHTML = row[cell];
185
            }else if(typeof row[cell] === "object"){
186
                this.DrawCellFromObject(row, cell, tCell);
187
            }
188
            tRow.appendChild(tCell);
189
        }
190
    };
191
192
    this.DrawCellFromObject = function(row, cell, tCell){
193
        for(var attr in row[cell]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
194
            if(typeof row[cell][attr] === "string"){
195
                tCell.innerHTML = row[cell][attr];
196
            }else if(typeof row[cell][attr] === "object"){
197
                for(var v in row[cell][attr]){
1 ignored issue
show
Complexity introduced by
A for in loop automatically includes the property of any prototype object, consider checking the key using hasOwnProperty.

When iterating over the keys of an object, this includes not only the keys of the object, but also keys contained in the prototype of that object. It is generally a best practice to check for these keys specifically:

var someObject;
for (var key in someObject) {
    if ( ! someObject.hasOwnProperty(key)) {
        continue; // Skip keys from the prototype.
    }

    doSomethingWith(key);
}
Loading history...
198
                    tCell.setAttribute(v, row[cell][attr][v]);
199
                }
200
            }
201
        }
202
    };
203
204
    this.footerProcessPaginationLinks = function(tSection){
205
        var pLinks = tSection.querySelectorAll(".paging a");
206
        if(pLinks.length > 0){
207
            for(var j = 0; j < pLinks.length; j++){
208
                pLinks[j].setAttribute("href", "javascript:void(0);");
209
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
210
            }
211
        }
212
    };
213
214
    this.clearSection = function(tSection){
215
        if(this.iePrior(9)){
216
            if(tSection.firstChild){
217
                while(tSection.firstChild){
218
                    tSection.removeChild(tSection.firstChild);
219
                }
220
            }
221
        }else{
222
            tSection.innerHTML = "";
223
        }
224
    };
225
226
    this.SetTheTableColumnsHoverEffect = function(tableContainer){
227
        if(this.iePrior(9)){
228
            return;
229
        }
230
        var tContainer = document.getElementById(tableContainer);
231
        var tHcells = tContainer.rows[0].cells;
232
        for(var i = 0; i < tHcells.length; i++){
233
            if(tHcells[i].firstChild.tagName === "A"){
234
                tHcells[i].firstChild.setAttribute("onmouseover", "table.ColumnHover('" + tableContainer + "'," + i + ");");
235
                tHcells[i].firstChild.setAttribute("onmouseout", "table.ColumnHover('" + tableContainer + "');");
236
            }
237
        }
238
        this.setPagingLinksSetActions(tContainer);
239
    };
240
241
    this.setPagingLinksSetActions = function(tContainer){
242
        var pLinks = tContainer.querySelectorAll("tfoot .paging a");
243
        if(pLinks.length > 0){
244
            for(var j = 0; j < pLinks.length; j++){
245
                pLinks[j].setAttribute("href", "javascript:void(0);");
246
                pLinks[j].setAttribute("onclick", "return table.GoPage(this);");
247
            }
248
        }
249
    };
250
251
    this.ColumnHover = function(tableContainer, index=null){
252
        if(!this.iePrior(9)){
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if !this.iePrior(9) is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
253
            var rows = document.getElementById(tableContainer).rows;
254
            var upto = rows.length - 1;
255
            if(index === null){
256
                return this.columnHoverRelease(rows, upto);
257
            }
258
            for(var i = 0; i < upto; i++){
259
                rows[i].cells[index].setAttribute("lang", "col-hover");
260
            }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
261
        }
262
    };
263
    this.columnHoverRelease = function(rows, upto){
264
        for(var i = 0; i < upto; i++){
265
            for(var j = 0; j < rows[i].cells.length; j++){
266
                if(rows[i].cells[j].lang){
267
                    rows[i].cells[j].removeAttribute("lang");
268
                }
269
            }
270
        }
271
    };
272
273
    this.getFilterFieldsByTbaleID = function(tableID){
274
        var fields = {filterBy: null, filter: null};
275
        var filterDiv = this.getFilterDivByTableIDOrNull(tableID);
276
        if(filterDiv !== null){
277
            var slctObj = filterDiv.getElementsByTagName("select")[0];
278
            var textObj = filterDiv.getElementsByTagName("input")[0];
279
            if(slctObj && slctObj.options[slctObj.selectedIndex].value !== "all"){
280
                fields.filterBy = slctObj.options[slctObj.selectedIndex].value;
281
            }
282
            if(textObj && textObj.value.length !== 0){
283
                fields.filter = encodeURIComponent(textObj.value.trim());
284
            }
285
        }
286
        return fields;
287
    };
288
289
    this.getFilterDivByTableIDOrNull = function(tableID){
290
        var res = null;
291
        if(document.getElementById(tableID).parentNode.getElementsByTagName("div").length > 0){
292
            for(var i = 0; i < document.getElementById(tableID).parentNode.getElementsByTagName("div").length; i++){
293
                if(document.getElementById(tableID).parentNode.getElementsByTagName("div")[i].getAttribute("class") === "filter"){
294
                    return document.getElementById(tableID).parentNode.getElementsByTagName("div")[i];
295
                }
296
            }
297
298
        }
299
        return res;
300
    };
301
302
    this.LoadData = function(tableContainer, rq){
303
        this.setVisability(tableContainer, false);
304
        if(window.XMLHttpRequest){
305
            xmlhttp = new XMLHttpRequest();/* code for IE7+, Firefox, Chrome, Opera, Safari */
306
        }else{ /** global: ActiveXObject */
307
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");/*code for IE6, IE5 */
0 ignored issues
show
Bug introduced by
The variable ActiveXObject seems to be never declared. If this is a global, consider adding a /** global: ActiveXObject */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
308
        }
309
        for(var i = 0; i < this.tail.length; i++){
310
            var ex_xmlhttp = this.tail.shift();
311
            ex_xmlhttp.abort();
312
        }
313
        xmlhttp.onreadystatechange = function(){
314
            if(xmlhttp.readyState === 4 && xmlhttp.status === 200){
315
                d = JSON.parse(xmlhttp.responseText);
316
                table.DrawSection(tableContainer, d.body);
317
                table.DrawSection(tableContainer, d.footer, "tfoot");
318
                table.LoadEndCalback(tableContainer);
319
                table.setVisability(tableContainer, true);
320
                if(typeof rq === "object"){
321
                    var hover = document.getElementById(rq.tableId)
322
                                .getElementsByTagName("th")[rq.colNo].lang;
323
                    if(hover){
324
                        table.ColumnHover(tableContainer, rq.colNo);
325
                    }
326
                }
327
            }
328
        };
329
        xmlhttp.open("GET", this.RequestToUrl(rq), true);
330
        xmlhttp.send();
331
        this.tail.push(xmlhttp); //put in tail to may later abort any previous
332
    };
333
334
    this.setVisability = function(tableContainer, rq){
335
        var tbl = document.getElementById(tableContainer);
336
        if(rq === true){
337
            tbl.style.filter = "none";
338
            tbl.style.opacity = "1";
339
            tbl.style.cursor = "auto";
340
        }else if(rq === false){
341
            tbl.style.filter = "blur(1px)";
342
            tbl.style.opacity = "0.8";
343
            tbl.style.cursor = "wait";
344
        }else{
345
            console.log("table error in the rq value"); /*Shows error*/
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
346
        }
347
    };
348
349
    this.getParent = function(obj, objType){
350
        while(obj && obj.tagName !== objType.toUpperCase()){
351
            obj = obj.parentNode;
352
        }
353
        return obj;
354
    };
355
356
    this.init = function(tableId){
357
        this.SetTheTableColumnsHoverEffect(tableId);
358
    };
359
360
    this.iePrior = function(v){
361
        var rv = false;
362
        if(/** global: navigator */ navigator.appName === 'Microsoft Internet Explorer'){
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
363
            var ua = navigator.userAgent;
364
            var re = new RegExp("MSIE ([0-9]{1,}[\.0-9]{0,})");
365
            if(re.exec(ua) !== null){
366
                rv = parseFloat(RegExp.$1);
367
            }
368
            rv = rv < v ? true : false;
369
        }
370
        return rv;
371
    };
372
    this.loadJS = function(src){
373
        var s = document.createElement('script');
374
        s.src = src;
375
        document.getElementsByTagName('head')[0].appendChild(s);
376
    };
377
    this.loadCSS = function(src){
378
        var s = document.createElement('link');
379
        s.href = src;
380
        s.rel = "stylesheet";
381
        document.getElementsByTagName('head')[0].appendChild(s);
382
    };
383
384
    this.LoadEndCalback = function(tableId){
385
        if(tableId){/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
386
        }
387
    };
388
    this.AppendRowCalback = function(tableId){
389
        if(tableId){/*Allows override*/
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
390
        }
391
    };
392
};
393
394
/** Moves custom created filter to the Table's filter
395
 * @param {string} filterId
396
 * @param {string} tableId
397
 * @param {boolean} delay - needed in case the table is istill not executed */
398
function moveSelectorToTheTableFilter(filterId, tableId, delay){
399
    if(delay === true){
400
        setTimeout(function(){
401
            var filterDiv = document.getElementById(tableId)
402
                    .getElementsByTagName("div")[0];
403
            filterDiv.appendChild(document.getElementById(filterId));
404
        }, 500);
405
    }else{
406
        var filterDiv = document.getElementById(tableId)
407
                .getElementsByTagName("div")[0];
408
        filterDiv.appendChild(document.getElementById(filterId));
409
    }
410
}
411
412
function changeListCustomFilter(selectObj){
413
    var name = selectObj.getAttribute("name");
414
415
    var inUrlPos = document.URL.indexOf(name);
416
    var url = inUrlPos !== -1 ?
417
            document.URL.substring(0, (inUrlPos - 1)) :
418
            document.URL;
419
420
    var value = selectObj.options[selectObj.selectedIndex].value;
421
    if(value !== "{!--Empty--!}"){
422
        var clue = document.URL.indexOf("?") > 0 ? "&" : "?";
423
        url += (clue + name + "=" + value);
424
    }
425
426
    location.assign(url);
427
}
428
429
430
function tablesLoadData(){
431
    var tables = document.getElementsByTagName("table");
432
    var envPrior9 = table.iePrior(9);
433
    for(var i = 0; i < tables.length; i++){
434
        var isProcessable = envPrior9 ?
435
                typeof tables[i]["data-table"] !== 'undefined' :
436
                tables[i].hasAttribute("data-table");
437
        if(isProcessable && tables[i].getAttribute("data-table") === "js"){
438
            table.LoadData(tables[i].id);
439
            table.SetTheTableColumnsHoverEffect(tables[i].id);
440
        }
441
    }
442
    /*if(table.iePrior(10)){
443
     table.loadJS("/add/helpers/table/add/json2.js");
444
     }
445
     
446
     if(table.iePrior(8)){ //can be used to add apropriate tables links modifications
447
     // loadCSS("/add/helpers/table/add/ie7-and-down.css");
448
     }*/
449
}
450
451
/*if(window.addEventListener){window.addEventListener('load',tablesLoadData,false);} else if(window.attachEvent){window.attachEvent('onload',tablesLoadData);}*/